package com.woniu.adapter;

import com.woniu.inlet.web.fo.ConfirmCurrentSellOrder;
import com.woniu.inlet.web.fo.ConfirmSellOrder;
import com.woniu.outlet.client.SendOrderMsgToPayFeign;
import com.woniu.outlet.client.mq.SellRevocationPayMQ;
import com.woniu.outlet.mysql.dao.ProductSellDao;
import com.woniu.outlet.mysql.po.*;
import com.woniu.outlet.redis.CodeOneRedisDao;
import com.woniu.outlet.redis.po.DailyCodeTOne;
import com.woniu.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * 产品卖出适配层
 */
@Component
@Transactional
@Slf4j
public class ProductSellAdapter {

    @Autowired
    private ProductSellDao dao;

    @Autowired
    private HoldProductAdapter holdProductAdapter;

    @Autowired
    private PersonalIncomeAdapter personalIncomeAdapter;

    @Autowired
    private CodeOneRedisDao redisDao;

    @Autowired
    private SendOrderMsgToPayFeign sendOrderMsgToPayFeign;

    /**
     * 定期和活期产品的卖出
     */
    public String fixedAndCurrentSell(FixedCurrentIncomeMySQL incomeMySQL) {
        BigDecimal amount=new BigDecimal("0");
        if (incomeMySQL.getProductType().equals("fixed")){
            amount=incomeMySQL.getTotalPrincipal().add(incomeMySQL.getIncome());
        }
        ProductSellMySQL mySQL = ProductSellMySQL.builder()
                .userId(incomeMySQL.getUserId())
                .productType(incomeMySQL.getProductType())
                .codeId(incomeMySQL.getCodeId())
                .name(incomeMySQL.getName())
                .sellShare("全部")
                .sellTime(DateUtil.getBuyTime())
                .holdDay(incomeMySQL.getHoldDay().toString())
                .sellCost(new BigDecimal("0"))
                .sellAmount(amount)
                .incomeId(incomeMySQL.getId().toString())
                .revocationShare("0")
                .revocationTime("0")
                .status(-1)
                .build();
        dao.insert(mySQL);
        return mySQL.getId().toString();
    }



    /**
     * 得到当前用户的这只基金的卖出明细
     *
     * @param userId
     * @param codeId
     */
    public List<ProductSellMySQL> getSellDetalis(Long userId, String codeId) {
        ProductSellMySQLExample example = new ProductSellMySQLExample();
        ProductSellMySQLExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andCodeIdEqualTo(codeId);
        criteria.andStatusEqualTo(0);
        return dao.selectByExample(example);
    }

    /**
     * 卖出基金和黄金
     *
     * @param userId
     * @param codeId
     * @param sellShare
     */
    public String sellFundOrGold(Long userId, String codeId, String sellShare) {
        //查询code份额
        HoldProductMySQL fg = holdProductAdapter.getFundOrGold(userId, codeId);
        BigDecimal totalShare = fg.getTotalShare();
        if (totalShare.toString().equals("0")
                || new BigDecimal(sellShare).compareTo(new BigDecimal("0")) <= 0
                || new BigDecimal(sellShare).compareTo(totalShare) > 0) {
            log.debug("不能卖出");
            return "n";
        }
        log.debug("可以卖出");
        //这只code的组成成分
        String fgAll = personalIncomeAdapter.getUserAllFundOrGold(userId, codeId, sellShare);
        holdProductAdapter.sellFund(fg, new BigDecimal(sellShare));
        log.debug("修改持有总数，原{}，现{}", fg.getTotalShare().add(new BigDecimal(sellShare)), fg.getTotalShare());
        return fgAll;
    }

    /**
     * 生成卖出记录
     *
     * @param userId
     * @param codeId
     * @param sellShare
     * @return
     */
    public String addSellOrder(Long userId,String productType, String codeId, String sellShare, String incomeId, String revocationShare) {
        log.debug("incomeId:{}", incomeId);
        DailyCodeTOne tOne = redisDao.findById(codeId).orElseThrow(NullPointerException::new);
        ProductSellMySQL mySQL = ProductSellMySQL.builder()
                .userId(userId)
                .productType(productType)
                .codeId(codeId)
                .name(tOne.getName())
                .sellAmount(new BigDecimal("0"))
                .sellCost(new BigDecimal("0"))
                .sellShare(sellShare)
                .sellTime(DateUtil.getBuyTime())
                .holdDay("0")
                .incomeId(incomeId)
                .revocationTime("0")
                .revocationShare(revocationShare)
                .status(0)
                .build();
        dao.insert(mySQL);
        return mySQL.getId().toString();
    }

    /**
     * 添加可撤销订单的日期
     *
     * @param sId
     * @param revocationDate
     */
    public void addRevocation(String sId, String revocationDate) {
        ProductSellMySQL mySQL = dao.selectByPrimaryKey(Long.valueOf(sId));
        mySQL.setRevocationTime(revocationDate);
        mySQL.setStatus(0);
        dao.updateByPrimaryKey(mySQL);
        log.debug("添加卖出订单的卖出确定时间成功");
    }

    /**
     * 撤销订单
     * 订单状态,0可撤销的订单，-1已买入，-2已撤销的订单，-3删除的订单
     * @param sId
     */
    public String revocationOrder(String sId) {
        //得到撤销请求的小时
        int hour = DateUtil.getHour();
        //得到订单的撤销时间
        ProductSellMySQL mySQL = dao.selectByPrimaryKey(Long.valueOf(sId));
        if(mySQL.getStatus()!=0){//不可撤销状态
            //不能撤销
            return "n";
        }
        String revocationTime = mySQL.getRevocationTime();
        //判断当前时间与撤销时间是否相等
        int i = DateUtil.getDays(revocationTime);
        if (i < 0) {
            //说明在撤销日期之前，可以撤销
            revocationShare(mySQL,sId);
            return "y";
        }
        if (i == 0) { //说明是撤销当日
            //判断当前时间是否小于撤销时间的15点之前，小于就可以撤销，否则不能撤销
            if (hour < 15) {
                //可以撤销
                revocationShare(mySQL,sId);
                return "y";
            }
        }
        //不能撤销
        return "n";

    }

    public void revocationShare(ProductSellMySQL mySQL,String sId) {
        String incomeId = mySQL.getIncomeId();
        String revocationShare = mySQL.getRevocationShare();
        String[] incomeIds = incomeId.split("-");
        String[] revocationShares = revocationShare.split("-");
        for (int k = 0; k < incomeIds.length; k++) {
            personalIncomeAdapter.revocationShares(incomeIds[k],revocationShares[k]);
        }
        holdProductAdapter.sellRevocationShares(mySQL.getUserId(),mySQL.getCodeId(),revocationShares);
        log.debug("用户份额撤销成功");
        updateStatus1To_2(sId);
        log.debug("用户订单撤销成功");
        sendOrderMsgToPayFeign.sendMessage(SellRevocationPayMQ.EXCHANGE,SellRevocationPayMQ.ROUTING_KEY,mySQL.getId().toString()+"/"+mySQL.getUserId());
        log.debug("发送到[支付模块][撤销通知]成功");
    }

    private void updateStatus1To_2(String sId) {
        ProductSellMySQL mySQL = dao.selectByPrimaryKey(Long.valueOf(sId));
        mySQL.setStatus(-2);
        dao.updateByPrimaryKey(mySQL);
    }


    /**
     * 支付模块卖出后确认金额等信息
     * @param sellMsgs
     */
    public void confirmSellOrder(ConfirmSellOrder confirmSell) {
        try {
            ProductSellMySQL mySQL = dao.selectByPrimaryKey(confirmSell.getId());
            mySQL.setSellShare(confirmSell.getSellShare());
            mySQL.setSellCost(confirmSell.getSellCost());
            mySQL.setHoldDay(confirmSell.getHoldDay());
            mySQL.setSellAmount(confirmSell.getSellAmount());
            mySQL.setStatus(-1);
            dao.updateByPrimaryKey(mySQL);
            log.debug("id={}，订单已成功卖出",confirmSell.getId());
            //删除已卖光的收益订单
            String[] incomeIds = mySQL.getIncomeId().split("-");
            for (String incomeId : incomeIds) {
                Long pid = Long.valueOf(incomeId);
                personalIncomeAdapter.delIncomeOrder(pid);
            }
            //删除已卖光的持有总数单子
            holdProductAdapter.delOrder(mySQL.getUserId(),mySQL.getCodeId());
        } catch (Exception e) {
            log.debug("确认卖出订单出现问题");
        }
    }

    /**
     * 获取用户的所有卖出订单
     * @param userId
     * @return
     */
    public List<ProductSellMySQL> findSellUserOrder(Long userId) {
        ProductSellMySQLExample example=new ProductSellMySQLExample();
        ProductSellMySQLExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andStatusNotEqualTo(-3);
        example.setOrderByClause("sell_time desc");
        return dao.selectByExample(example);
    }

    public Long sellCurrent(ConfirmCurrentSellOrder currentSellOrder) {
        ProductSellMySQL mySQL = dao.selectByPrimaryKey(currentSellOrder.getId());
        mySQL.setSellCost(currentSellOrder.getSellCost());
        mySQL.setSellAmount(currentSellOrder.getSellAmount());
        dao.updateByPrimaryKey(mySQL);
        return Long.valueOf(mySQL.getIncomeId());
    }
}
